{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "%use gral"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "import java.awt.Color\n",
    "import java.util.*\n",
    "\n",
    "// ported from Gral's ConvolutionExample.java\n",
    "\n",
    "val SAMPLE_COUNT = 200\n",
    "val KERNEL_VARIANCE = 5.0\n",
    "val COLOR1 = Color(55, 170, 200)\n",
    "val COLOR2 = Color(200, 80, 75)\n",
    "\n",
    "// Generate 200 data points\n",
    "val data = DataTable(java.lang.Double::class.java, java.lang.Double::class.java).apply {\n",
    "    val r = Random()\n",
    "    for (i in 0..SAMPLE_COUNT - 1) {\n",
    "        val x = i.toDouble() / 2.0 / Math.PI\n",
    "        val yError = Math.sqrt(3.0 * 0.1) * r.nextGaussian()\n",
    "        val y = 10.0 * Math.sin(x / 5.0) + yError * yError * yError\n",
    "        add(x, y)\n",
    "    }\n",
    "}\n",
    "\n",
    "val ds = DataSeries(\"Data\", data, 0, 1)\n",
    "\n",
    "// Create a smoothed data series from a binomial (near-gaussian) convolution filter\n",
    "val kernelLowpass = Kernel.getBinomial(KERNEL_VARIANCE).normalize()\n",
    "val dataLowpass = Convolution(data, kernelLowpass, Filter.Mode.REPEAT, 1)\n",
    "val dsLowpass = DataSeries(\"Lowpass\", dataLowpass, 0, 1)\n",
    "\n",
    "// Create a derived data series from a binomial convolution filter\n",
    "val kernelHighpass = Kernel.getBinomial(KERNEL_VARIANCE).normalize().negate().add(Kernel(1.0))\n",
    "val dataHighpass = Convolution(data, kernelHighpass, Filter.Mode.REPEAT, 1)\n",
    "val dsHighpass = DataSeries(\"Highpass\", dataHighpass, 0, 1)\n",
    "\n",
    "// Create a new data series that calculates the moving average using a custom convolution kernel\n",
    "val kernelMovingAverageSize = Math.round(4.0 * KERNEL_VARIANCE).toInt()\n",
    "val kernelMovingAverage = Kernel.getUniform(kernelMovingAverageSize, kernelMovingAverageSize - 1, 1.0).normalize()\n",
    "val dataMovingAverage = Convolution(data, kernelMovingAverage, Filter.Mode.OMIT, 1)\n",
    "val dsMovingAverage = DataSeries(\"Moving Average\", dataMovingAverage, 0, 1)\n",
    "\n",
    "// Create a new data series that calculates the moving median\n",
    "val kernelMovingMedianSize = Math.round(4.0 * KERNEL_VARIANCE).toInt()\n",
    "val dataMovingMedian = Median(data, kernelMovingMedianSize, kernelMovingMedianSize - 1, Filter.Mode.OMIT, 1)\n",
    "val dsMovingMedian = DataSeries(\"Moving Median\", dataMovingMedian, 0, 1)\n",
    "\n",
    "fun XYPlot.formatLine(series: DataSeries, color: Color) {\n",
    "    setPointRenderers(series, null as List<PointRenderer>?)\n",
    "    val line = DefaultLineRenderer2D().apply { setColor(color) }\n",
    "    setLineRenderers(series, line)\n",
    "}\n",
    "\n",
    "// Create a new xy-plot\n",
    "XYPlot(ds, dsLowpass, dsHighpass, dsMovingAverage, dsMovingMedian).apply {\n",
    "\n",
    "    // Format plot\n",
    "    insets = Insets2D.Double(20.0, 40.0, 40.0, 40.0)\n",
    "    isLegendVisible = true\n",
    "\n",
    "    // Format legend\n",
    "    legend.orientation = Orientation.HORIZONTAL\n",
    "    legend.alignmentY = 1.0\n",
    "\n",
    "    // Format data series as lines of different colors\n",
    "    formatLine(ds, Color.BLACK)\n",
    "    formatLine(dsLowpass, COLOR1)\n",
    "    formatLine(dsHighpass, GraphicsUtils.deriveDarker(COLOR1))\n",
    "    formatLine(dsMovingAverage, COLOR2)\n",
    "    formatLine(dsMovingMedian, GraphicsUtils.deriveDarker(COLOR2))\n",
    "}.show(1000.0, 500.0)\n"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Kotlin",
   "language": "kotlin",
   "name": "kotlin"
  },
  "language_info": {
   "file_extension": "kt",
   "name": "kotlin"
  },
  "pycharm": {
   "stem_cell": {
    "cell_type": "raw",
    "source": [],
    "metadata": {
     "collapsed": false
    }
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}